package com.engine.cn.base.streams;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class SteamsTests {

    public Stream<String> create(String[] arr) {
        //第一种创建方式 Stream<String> stream = Arrays.asList(arr).stream();
        //第二种创建方式 Stream<String> stream = Arrays.stream(arr);
        //第三种创建方式
        return Stream.of(arr);
    }

    /**
     * filter过滤
     *
     * @param arr 原数组
     * @return 返回值
     */
    public List<String> filter(String[] arr) {
        return create(arr).filter(f -> f.contains("a")).collect(Collectors.toList());
    }

    /**
     * map映射转换
     *
     * @param arr 原数组
     * @return 返回值
     */
    public List<String> map(String[] arr) {
        return create(arr).map(String::toUpperCase).collect(Collectors.toList());
    }

    /**
     * 合并多个集合或拆分字符串、处理嵌套对象
     *
     * @return List<String>
     */
    public List<String> flatMap() {
        List<String> team1 = Arrays.asList("Alice", "Bob");
        List<String> team2 = Arrays.asList("Bom", "Kitty");
        List<String> team3 = Arrays.asList("Lily", "Lucy");
        List<String> team4 = Arrays.asList("Alice Bob", "Hello Kitty");
        List<String> team5 = team4.stream().flatMap(t -> Arrays.stream(t.split(" "))).toList();
        System.out.println("team5==>" + team5);
        List<String> team6 = Stream.of(team1, team2, team3).flatMap(Collection::stream).toList();
        System.out.println("team6==>" + team6);
        List<Order> orders = List.of(new Order(List.of("Apple", "Banana")), new Order(List.of("Orange", "Grape")));
        return orders.stream().flatMap(order -> order.getItems().stream()).toList();
    }

    /**
     * distinct 去重
     *
     * @return List<Integer>
     */
    public List<Integer> distinct() {
        Integer[] arr = {1, 1, 1, 5, 3, 22, 2, 2};
        return Arrays.stream(arr).distinct().toList();
    }

    /**
     * sorted 排序
     *
     * @return List<Integer>
     */
    public List<Order> sorted() {
        List<Order> orders = List.of(new Order(new BigDecimal(12)), new Order(new BigDecimal(10)));
        return orders.stream().sorted(Comparator.comparing(Order::getPrice)).toList();
    }

    /**
     * 限制元素数量
     *
     * @param args 原数组
     * @return List<String>
     */
    public List<String> limit(String[] args) {
        return Stream.of(args).limit(2).toList();
    }

    /**
     * 跳过元素
     *
     * @param args 原数组
     * @return List<String>
     */
    public List<String> skip(String[] args) {
        return Stream.of(args).skip(1).toList();
    }

    /**
     * reduce 是 Stream API 中一个非常强大的终端操作，它可以将流中的元素反复结合起来，得到一个单一的值。
     * reduce 操作在函数式编程中被称为"折叠"(fold)，在实际开发中有广泛的应用场景。
     *
     * @param args 原数组
     * @return Integer
     */
    public Integer reduce(Integer[] args) {
        return Stream.of(args).reduce(0, Integer::sum);
    }

    public static void main(String[] args) {
        SteamsTests steamTests = new SteamsTests();
        String[] arr = {"aoe", "iuv", "kk", "pp", "apo"};
        List<String> filter = steamTests.filter(arr);
        System.out.println("filter==>" + filter);
        List<String> map = steamTests.map(arr);
        System.out.println("map==>" + map);
        List<String> flatMap = steamTests.flatMap();
        System.out.println("flatMap==>" + flatMap);
        List<Integer> distinct = steamTests.distinct();
        System.out.println("distinct==>" + distinct);
        List<Order> orders = steamTests.sorted();
        orders.forEach(order -> System.out.println("price==>" + order.getPrice()));
        List<String> limit = steamTests.limit(arr);
        System.out.println("limit==>" + limit);
        List<String> skip = steamTests.skip(arr);
        System.out.println("skip==>" + skip);
        Integer reduce = steamTests.reduce(new Integer[]{1, 2, 3, 4, 5,});
        System.out.println("reduce==>" + reduce);
    }
}
